package com.gigmissions.client;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.gigmissions.client.model.Photo;
import com.gigmissions.client.model.Venue;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.geocode.Geocoder;
import com.google.gwt.maps.client.geocode.LatLngCallback;
import com.google.gwt.maps.client.geocode.LocationCallback;
import com.google.gwt.maps.client.geocode.Placemark;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.Point;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;

public class VenueServiceUtil {
	
	 final static VenueServiceAsync service = (VenueServiceAsync) Registry.get(Gwtgigmissions.VENUE_SERVICE);
	 
	 public final static long WEEK_MILLISECONDS = 604800000L;
	
	 public static ListStore<BeanModel> getVenues(MapWidget map){
		 
		 return getVenues(map,System.currentTimeMillis() - WEEK_MILLISECONDS,System.currentTimeMillis() + WEEK_MILLISECONDS);
	 }
	 
	 public static ListStore<BeanModel> getVenues(MapWidget map, final long startTime,final long endTime){
		
	    final double neLat = map.getBounds().getNorthEast().getLatitude();
	    final double neLng = map.getBounds().getNorthEast().getLongitude();
	    final double swLat = map.getBounds().getSouthWest().getLatitude();
	    final double swLng = map.getBounds().getSouthWest().getLongitude();
	    
	    RpcProxy<List<Venue>> proxy = new RpcProxy<List<Venue>>() {
		      @Override
		      protected void load(Object loadConfig, AsyncCallback<List<Venue>> callback) {
		    	    service.getVenues(neLat, neLng, swLat, swLng, startTime, endTime, callback);
		      }
		    };
		    
		ListLoader<ListLoadResult<Venue>> loader = new BaseListLoader<ListLoadResult<Venue>>(proxy, new BeanModelReader());
		
	    ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
 		loader.load();
	    
	    return store;
	}
	 
	 public static ListStore<BeanModel> getPhotos(MapWidget map){
		 return getPhotos(map,System.currentTimeMillis() - WEEK_MILLISECONDS,System.currentTimeMillis() + WEEK_MILLISECONDS);
	 }

	 public static ListStore<BeanModel> getPhotos(MapWidget map, final long startTime,final long endTime){
			 
		RpcProxy<List<Photo>> proxy = new RpcProxy<List<Photo>>() {
		      @Override
		      protected void load(Object loadConfig, AsyncCallback<List<Photo>> callback) {
		        service.getVenuePhotos(callback);
		      }
		    };
	
	   ListLoader<ListLoadResult<Photo>> loader = new BaseListLoader<ListLoadResult<Photo>>(proxy, new BeanModelReader());
	   ListStore<BeanModel> store = new ListStore<BeanModel>(loader);
	   loader.load();
	   return store;
	 }
	 
	 public static List<Placemark> geocodeAddress(String address){
		 
		 
		 final Geocoder geocoder = new Geocoder(); 
		 
		 final List<Placemark> placemarks = new ArrayList<Placemark>();
		 
		geocoder.getLocations(address, new LocationCallback(){
		
			@Override
			public void onFailure(int statusCode) {
				//this just means the list isn't filled.
				GWT.log("Error geocoding " + statusCode , new IllegalStateException("Geocoding error."));
			}
		
			@Override
			public void onSuccess(JsArray<Placemark> locations) {
				// TODO Auto-generated method stub
				for(int index=0;index<locations.length();index++)
				placemarks.add(locations.get(index));
			}
			
			
			
		});
		 
		return placemarks;
	
		 
	 }

	 public static void geocodeAddressAndShowAddressDialog(final String name,final String address,final MapWidget map){
		 
		 
		final Geocoder geocoder = new Geocoder(); 
		geocoder.getLocations(address, new LocationCallback(){
		
			@Override
			public void onFailure(int statusCode) {
				//this just means the list isn't filled.
				final Listener<MessageBoxEvent> l = new Listener<MessageBoxEvent>() {  
					public void handleEvent(MessageBoxEvent ce) {  
				
					}  
				};  
				MessageBox.alert("Address not found.", "Couldn't find the address \"" + address + "\", did you type it correctly?",l);  
			}
		
			@Override
			public void onSuccess(JsArray<Placemark> locations) {

				ChoosePlacemarkContainer container = new ChoosePlacemarkContainer(map);
				container.setPlacemarkName(name);
				container.addPlacemarks(locations);
				ChooseAddressDialog addressDialog = new ChooseAddressDialog(map,container);
				addressDialog.show();
				
				
			}
			
			
			
		});
		 
		
	
		 
	 }
	 
	 public static void zoomToAddressAndAddMarker(String address,final MapWidget map, final String infoWindowContent){
		 
		 
			final Geocoder geocoder = new Geocoder(); 
			geocoder.getLatLng(address, new LatLngCallback(){

				@Override
				public void onFailure() {
					// TODO Auto-generated method stub
					
				}

				@Override
				public void onSuccess(final LatLng point) {
					// TODO Auto-generated method stub\
					map.setCenter(point);
					map.setZoomLevel(15);
					Icon icon = Icon.newInstance("/venues/venueicon.png");
					icon.setIconAnchor(Point.newInstance(24, 24));
					MarkerOptions mo = MarkerOptions.newInstance(icon);
					Marker marker = new Marker(point,mo);
					final InfoWindowContent content = new InfoWindowContent(infoWindowContent);
					marker.addMarkerClickHandler(new MarkerClickHandler(){

						@Override
						public void onClick(MarkerClickEvent event) {
							map.getInfoWindow().open(point,content);
						}
						
						
						
					});
					map.addOverlay(marker);
					map.getInfoWindow().open(point,content);
					
				}
			
				
				
				
				
			});
			 
			
		
			 
		 }
	 
 
}
